package com.cmcc.groupcontacts.common;

import java.lang.reflect.Method;
import java.util.ArrayList;
import java.util.Date;
import java.util.List;

import android.app.Notification;
import android.app.NotificationManager;
import android.app.PendingIntent;
import android.content.Context;
import android.content.Intent;
import android.os.RemoteException;
import android.telephony.TelephonyManager;
import android.util.Log;

import com.android.internal.telephony.ITelephony;
import com.cmcc.groupcontacts.MainApp;
import com.cmcc.groupcontacts.firewall.activity.FirewallConfigModeActivity;
import com.cmcc.groupcontacts.firewall.activity.FirewallTabActivity;
import com.cmcc.groupcontacts.firewall.dao.model.CallListVO;
import com.cmcc.groupcontacts.util.DateUtil;
import com.cmcc.groupcontacts.util.ExceptionHandler;
import com.yinhai.activity.R;

/**
 * 来电接收器
 * 
 * @author
 * 
 */
public class CallReceiver extends BaseReceiver {
	private static final String LOG_TAG = "CallReceiver";

	private boolean isNeedBlockCall = false; // 是否需要拦截来电
	private Date startRingDate = null; // 开始响铃时间
	private Date endRingDate = null; // 结束响铃时间

	/** 来电拦截通知ID集合 */
	public static List<Integer> notificationIdList = new ArrayList<Integer>();

	@Override
	public void onReceive(Context context, Intent intent) {
		try {
			String incomingNumber = null;
			final ITelephony telephony = getITelephony(context);
			final TelephonyManager telMgr = (TelephonyManager) context
					.getSystemService(Context.TELEPHONY_SERVICE);
			switch (telMgr.getCallState()) {
			case TelephonyManager.CALL_STATE_RINGING:
				Log.v(LOG_TAG, "触发响铃状态的开始响铃时间");
				startRingDate = new Date();
				incomingNumber = intent
						.getStringExtra(TelephonyManager.EXTRA_INCOMING_NUMBER);
				if (isNeedBlockCall(incomingNumber)) {
					try {
						Log.v(LOG_TAG, "正在挂断电话：" + incomingNumber);
						MainApp.blockedNumber = incomingNumber;
						MainApp.blockedType = CallListVO.TYPE_OTHER;
						telephony.endCall();
						showCallNotification(context, incomingNumber);
					} catch (RemoteException e) {
						ExceptionHandler.handle(e, "来电拦截挂断时出错");
					}
				}
				break;
			case TelephonyManager.CALL_STATE_OFFHOOK:
				// 主动挂断，取消拦截骚扰电话
				startRingDate = null;
				break;
			case TelephonyManager.CALL_STATE_IDLE: // 拦截指定骚扰时长的陌生电话
				// TODO: [BUG]判断是主动挂断还是被动挂断，CallNotifier好像是底层的，用不了
				// TODO: [优化]骚扰电话拦截只是从通话记录中删除，系统通知栏的提醒不会消失，只有Root权限下有办法进行处理

				// 快速拨号并挂断时，可能无法触发TelephonyManager.CALL_STATE_RINGING状态，而更改为首次触发TelephonyManager.CALL_STATE_IDLE状态
				if (startRingDate == null) {
					Log.v(LOG_TAG, "未触发响铃状态的开始响铃时间");
					startRingDate = new Date();
				} else {
					Log.v(LOG_TAG,
							"开始响铃时间: " + DateUtil.dateToStrLong(startRingDate));
					endRingDate = new Date();
					Log.v(LOG_TAG,
							"结束响铃时间: " + DateUtil.dateToStrLong(endRingDate));
					if (isNeedBlockDisturbCall()) {
						incomingNumber = intent
								.getStringExtra(TelephonyManager.EXTRA_INCOMING_NUMBER);
						Log.v(LOG_TAG, incomingNumber + "是骚扰电话");
						MainApp.blockedNumber = incomingNumber;
						MainApp.blockedType = CallListVO.TYPE_DISTURB;
						showCallNotification(context, incomingNumber);
					}
					release();
				}
				break;
			}
		} catch (Exception e) {
			ExceptionHandler.handle(e, "来电拦截处理时出错");
		}
	}

	/*
	 * 通过反射获取电话接口
	 */
	private ITelephony getITelephony(Context context) {
		TelephonyManager telephonyMgr = (TelephonyManager) context
				.getSystemService(Context.TELEPHONY_SERVICE);
		try {
			Method getITelephonyMethod = TelephonyManager.class
					.getDeclaredMethod("getITelephony", (Class[]) null);
			getITelephonyMethod.setAccessible(true);
			return (ITelephony) getITelephonyMethod.invoke(telephonyMgr,
					(Object[]) null);
		} catch (Exception e) {
			ExceptionHandler.handle(e, "通过反射获取电话接口时出错");
			return null;
		}
	}

	/*
	 * 校验是否需要拦截来电
	 */
	private boolean isNeedBlockCall(String number) {
		boolean isFirewallOpen = PreferenceManager.getFirewallState();
		// 是否开启拦截功能
		if (isFirewallOpen) {
			switch (PreferenceManager.getFirewallMode()) {
			case FirewallConfigModeActivity.MODE_STANDARD: // 智能拦截
			case FirewallConfigModeActivity.MODE_BLOCK_BLACK: // 只拦截黑名单
				isNeedBlockCall = isExistedInBlackList(number);
				break;
			case FirewallConfigModeActivity.MODE_PASS_WHITE: // 只放行白名单
				isNeedBlockCall = !isExistedInWhiteList(number);
				break;
			case FirewallConfigModeActivity.MODE_PASS_LOCAL_CONTACTS: // 只放行本地通信录
				isNeedBlockCall = !isExistedInLocalContacts(number);
				break;
			case FirewallConfigModeActivity.MODE_PASS_ALL_CONTACTS: // 只放行本地和集团通信录
				isNeedBlockCall = (!isExistedInLocalContacts(number) && !isExistedInAllContacts(number));
				break;
			case FirewallConfigModeActivity.MODE_BLOCK_ALL: // 全部拦截
				isNeedBlockCall = true;
				break;
			case FirewallConfigModeActivity.MODE_CUSTOMIZE: // 自定义拦截规则
				boolean isBlockBlackList = PreferenceManager
						.getFirewallModeState(
								PreferenceManager.CONFIG_FIREWALL_MODE_BLACK,
								true);
				if (isBlockBlackList) {
					// 拦截黑名单
					if (isExistedInBlackList(number)) {
						isNeedBlockCall = true;
						break;
					}
				}
				boolean isPassWhiteList = PreferenceManager
						.getFirewallModeState(
								PreferenceManager.CONFIG_FIREWALL_MODE_WHITE,
								true);
				if (isPassWhiteList) {
					// 放行白名单
					if (isExistedInWhiteList(number)) {
						isNeedBlockCall = false;
						break;
					}
				}
				boolean isPassLocalContactsCall = !PreferenceManager
						.getFirewallModeState(
								PreferenceManager.CONFIG_FIREWALL_MODE_LOCAL_CONTACTS_CALL,
								false);
				if (isPassLocalContactsCall) {
					// 在本地通信录中存在则放行
					if (isExistedInLocalContacts(number)) {
						isNeedBlockCall = false;
						break;
					}
				} else {
					// 在本地通信录中存在则拦截
					if (isExistedInLocalContacts(number)) {
						isNeedBlockCall = true;
						break;
					}
				}
				boolean isPassGroupContactsCall = !PreferenceManager
						.getFirewallModeState(
								PreferenceManager.CONFIG_FIREWALL_MODE_GROUP_CONTACTS_CALL,
								false);
				if (isPassGroupContactsCall) {
					// 在集团通信录中存在则放行
					if (!isExistedInLocalContacts(number)
							&& isExistedInAllContacts(number)) {
						isNeedBlockCall = false;
						break;
					}
				} else {
					// 在集团通信录中存在则拦截
					if (!isExistedInLocalContacts(number)
							&& isExistedInAllContacts(number)) {
						isNeedBlockCall = true;
						break;
					}
				}
				boolean isPassStrangerCall = !PreferenceManager
						.getFirewallModeState(
								PreferenceManager.CONFIG_FIREWALL_MODE_STRANGER_CALL,
								false);
				if (isPassStrangerCall) {
					// 放行陌生人
					isNeedBlockCall = false;
				} else {
					// 拦截陌生人
					isNeedBlockCall = true;
				}
				break;
			}
		}
		return isNeedBlockCall;
	}

	/*
	 * 校验是否需要拦截骚扰电话
	 */
	private boolean isNeedBlockDisturbCall() {
		if (isNeedBlockCall || endRingDate == null) {
			return false;
		}

		boolean isBlockDisturbCallOpen = false; // 是否开启防骚扰来电拦截功能
		boolean isFirewallOpen = PreferenceManager.getFirewallState();
		// 是否开启拦截功能
		if (isFirewallOpen) {
			switch (PreferenceManager.getFirewallMode()) {
			case FirewallConfigModeActivity.MODE_STANDARD:
			case FirewallConfigModeActivity.MODE_BLOCK_ALL:
				isBlockDisturbCallOpen = true;
				break;
			case FirewallConfigModeActivity.MODE_CUSTOMIZE:
				isBlockDisturbCallOpen = PreferenceManager
						.getFirewallModeState(
								PreferenceManager.CONFIG_FIREWALL_MODE_DISTURB_CALL,
								true);
				break;
			}
		}
		if (isBlockDisturbCallOpen) {
			// 是否需要拦截骚扰电话
			long ringTimespan = (endRingDate.getTime() - startRingDate
					.getTime());
			if (ringTimespan <= 2000) {
				return true;
			}
		}
		return false;
	}

	/*
	 * 显示来电拦截系统栏通知
	 */
	private void showCallNotification(Context context, String number) {
		// TODO: [优化]合并多条提醒
		NotificationManager notificationManager = (NotificationManager) context
				.getSystemService(Context.NOTIFICATION_SERVICE);
		Notification notification = new Notification(R.drawable.sty2_prompt,
				"集团通信录来电拦截通知", System.currentTimeMillis());
		// TODO: 拦截提示音
		notification.defaults = Notification.DEFAULT_SOUND;
		notification.flags = Notification.FLAG_AUTO_CANCEL;
		Intent notificationIntent = new Intent(context,
				FirewallTabActivity.class);
		notificationIntent.setFlags(Intent.FLAG_ACTIVITY_NEW_TASK
				| Intent.FLAG_ACTIVITY_RESET_TASK_IF_NEEDED);
		notificationIntent.putExtra(FirewallTabActivity.TAB_INDEX, 1);
		PendingIntent pendingIntent = PendingIntent.getActivity(context, 0,
				notificationIntent, PendingIntent.FLAG_UPDATE_CURRENT);
		if (MainApp.blockedType != CallListVO.TYPE_DISTURB) {
			notification.setLatestEventInfo(context, "集团通信录提醒", "已拦截" + number
					+ "的来电", pendingIntent);
		} else {
			notification.setLatestEventInfo(context, "集团通信录提醒", "已拦截" + number
					+ "的响一声电话", pendingIntent);
		}
		int notificationId = CoreService.notificationIdCounter++;
		notificationIdList.add(notificationId);
		notificationManager.notify(notificationId, notification);
	}

	private void release() {
		isNeedBlockCall = false;
		startRingDate = null;
		endRingDate = null;
	}
}
